using System;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Sedna.Core.Controller;
using Sedna.Core.Controller.Configurations;
using Sedna.Core.Controller.Configurations.Enums;
using Sedna.Core.Controls.Support;
using Sedna.Core.Controls.Support.Javascript;
using Sedna.Core.Globalization;

namespace Sedna.Core.Controls
{
	/// <summary>
	/// Frame is a HTML table, that have a header and can be expanded and collapsed to header
	/// dynamically on the client. Frame incapsulates frame processing logic.
	/// </summary>
	[ParseChildren(true)]
	public class Frame: BaseControl, ILabelledControl, INamingContainer, IClientScriptingControl
	{
		protected const string javascriptKey="coreims.javascript.frame";


		private bool isStatic=false;
//		private string text;
		private string textKey;

		private FrameState onState=FrameState.Expanded;
		private FrameState offState=FrameState.Collapsed;
		private FrameState state=FrameState.Expanded;
		private bool collapseOthers=true;
        private bool resetStateOnPostBack = false;

		private Control header;
		private Control content;

		private System.Web.UI.LiteralControl headerButton=new System.Web.UI.LiteralControl("( )");
		private HtmlInputHidden stateControl=new HtmlInputHidden();
		private HtmlInputHidden frameTitle=new HtmlInputHidden();
		
		private Unit height=Unit.Pixel(0);

        #region Properties

	    public new IFrameConfiguration Configuration
	    {
            get { return (IFrameConfiguration) base.Configuration; }
            set { base.Configuration = value; }
	    }
	    
        /// <summary>
		/// Determines whether the frame can be turned on and off on the client.
		/// </summary>
		public bool IsStatic
		{
			get { return isStatic; }
			set { isStatic=value; }
		}

		public string TextKey
		{
			get { return textKey; }
			set { textKey=value; }
		}

		public string Text
		{
			get { return frameTitle.Value; }
			set { frameTitle.Value=value; }
		}


	    protected override HtmlTextWriterTag TagKey
	    {
	        get { return HtmlTextWriterTag.Table; }
	    }

	    public FrameState OnState
		{
			get { return onState; }
			set { onState = value; }
		}

		public FrameState OffState
		{
			get { return offState; }
			set { offState = value; }
		}
		public FrameState State
		{
			get { return state; }
			set { state = value; }
		}

		/// <summary>
		/// Determines whether other frames on the page should be turned off when this frame is turned on.
		/// </summary>
		public bool CollapseOthers
		{
			get { return collapseOthers; }
			set { collapseOthers = value; }
		}


		public virtual Control Header
		{
			get { return header; }
			set
			{
				Controls.Remove(header);
				header = value;
				//header.ID="header";
				Controls.Add(header);
			}
		}

		public virtual Control Content
		{
			get { return content; }
			set
			{
				Controls.Remove(content);
				content = value;
				/*if (content.ID==null)
				{
					content.ID="content";				
				}*/
				Controls.Add(content);
			}
		}

		public override bool ClientScriptingEnabled
		{
			get { return !isStatic; }
			set { isStatic=!value; }
		}

		/// <summary>
		/// The property is overriden as it should affect only the body of the frame, not
		/// the whole frame with header. 
		/// </summary>
		public override Unit Height
		{
			get { return height; }
			set { height = value; }
        }

	    public bool ResetStateOnPostBack
	    {
	        get { return resetStateOnPostBack; }
	        set { resetStateOnPostBack = value; }
	    }

	    #endregion

        public Frame(): base()
		{
            configurationId = "configuration.default.Frame";
		}
	    
	    
	    public Frame(IConfiguration configuration): base(configuration)
	    {
	    }
	    

	    protected override void Build()
	    {
            Width = Unit.Percentage(100);
            base.Build();
            ClientScriptingEnabled = Configuration.ClientScriptingEnabled;
            ClientVariable = Configuration.ClientVariable;
            IsStatic = Configuration.IsStatic;
            TextKey = Configuration.TextKey;
            Text = Configuration.Label;
            OffState = Configuration.OffState;
            State = Configuration.State;
            CollapseOthers = Configuration.CollapseOthers;
            Height = Configuration.Height;
            ResetStateOnPostBack = Configuration.ResetStateOnPostBack;
        }

	    protected override void AddAttributesToRender(HtmlTextWriter writer)
		{
			//writer.AddAttribute(HtmlTextWriterAttribute.Width, Unit.Percentage(100).ToString());
			writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
			writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
			base.AddAttributesToRender(writer);

/*
			if (ID==null) //ASP.NET doesn't add id attribute, if ID property is null
			{
				writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
			}
*/
		}

		protected override void OnLoad(EventArgs e)
		{
			RestoreState();
			base.OnLoad(e);
		}

		protected override void CreateChildControls()
		{
			base.CreateChildControls();

			stateControl.ID="frame_state";
			stateControl.EnableViewState=false;
			Controls.Add(stateControl);
			frameTitle.ID="frame_title";
			frameTitle.EnableViewState=false;
			Controls.Add(frameTitle);
			/*
			if (header!=null)
			{
				Controls.Add(header);
			}
			if (content!=null)
			{
				Controls.Add(content);
			}
			*/
		}

		protected override void OnPreRender(EventArgs e)
		{
			base.OnPreRender(e);
			if (!isStatic)
			{
			    DeclareScriptVariable();
//				EnableClientScripting();
				stateControl.Value=state.ToString();
				BuildHeaderButton();

			}
			Text=configuration.GetLocalizedPostfixLabel(TextKey,Text);
            switch(State)
            {
                case FrameState.Expanded:
                    CssClass = "frame-display-expanded";
                    break;
                case FrameState.Collapsed:
                    CssClass = "frame-display-collapsed";
                    break;
                case FrameState.Hidden:
                    CssClass = "frame-display-hidden";
                    break;
            }
//		    Style["display"] = (State == FrameState.Expanded || State == FrameState.Collapsed) ? "run-in" : "none";
            //if (!this.Enabled)
            //    foreach (Control control in content.Controls)
            //    {
            //        if (control is WebControl)
            //        {
            //            WebControl wc = control as WebControl;
            //            wc.Enabled = false;
            //        }
            //    }

		}

		protected override void Render(HtmlTextWriter writer)
		{		    
			RenderBeginTag(writer);

            writer.Write("<tr height=\"25\" >");
            writer.Write("<td id=\""+ClientID+"_header\" class=\"filter-on-state\">");

			writer.Write("<table width=\"100%\" height=\"100%\" >");
			writer.Write("<tr>");
			writer.Write("<td>");
			writer.Write("<div style=\"height: 100%; overflow: hidden; \">");

			if (!isStatic)
			{
				headerButton.RenderControl(writer);
			}
			writer.Write("<span id=\""+ClientID+"_title\">");
			writer.Write(Text);
			writer.Write(" </span>");
			writer.Write("</div>");
			writer.Write("</td>");

			if (header!=null)
			{
				writer.Write("<td class=\"rightalign\">");
				header.RenderControl(writer);
				writer.Write("</td>");
			}

			writer.Write("</tr>");
			writer.Write("</table>");
			
			writer.Write("</td>");
			writer.Write("</tr>");

			writer.Write("<tr height=\"2\">");
			writer.Write("<td>");	
			writer.Write("</td>");
			writer.Write("</tr>");

            writer.Write(String.Format("<tr id=\"{0}_bar\" style=\"height:{1}\" >", ClientID, height)); 
            writer.Write("<td valign=\"top\">"); 

			if (content!=null)
			{
				content.RenderControl(writer);
			}
			
			writer.Write("</td>");
            writer.Write("</tr>");

			RenderEndTag(writer);

			if (!isStatic)
			{
				stateControl.RenderControl(writer);
				frameTitle.RenderControl(writer);
			}

		}

		private void BuildHeaderButton()
		{
			string html=String.Empty;
            html += String.Format("<a href=\"#\" onclick=\"Framework.instance.getControlByName(\'{0}\').switchState();\">", NodeName);					
			html+="<img id=\""+ClientID+"_image\" class=\"noborder\" align=\"absmiddle\" src=\""+ImageManager.Relate(this, "ar2u.gif")+"\">";
			html+="</a>&nbsp;";

			headerButton.Text=html;
		}

		private void RestoreState()
		{
			EnsureChildControls();
            if (Page.IsPostBack && ResetStateOnPostBack)
            {
                State = Configuration.State;
                return;
            }

			if (stateControl.Value!=null&&stateControl.Value!=String.Empty)
			{
				state=(FrameState)FrameState.Parse(typeof(FrameState), stateControl.Value, true);	
			}
		}

//		protected virtual void EnableClientScripting()
//		{
//			ControlUtil.EnsureIdAttribute(this);
//            JavascriptController.Current.DeclareClass(JavascriptClass);
//            JavascriptController.Current.DeclareObject(ControlUtil.GetClientVariable(this), JavascriptClass, BuildScriptParameters().ToArray());
//		}

		protected override IDictionary BuildScriptParameters()
		{
            IDictionary parameters = base.BuildScriptParameters();

			parameters.Add("id", ClientID);
			parameters.Add("stateControlId", stateControl.ClientID);
			parameters.Add("titleControlId", frameTitle.ClientID);
			parameters.Add("onState", OnState.ToString());
			parameters.Add("offState", OffState.ToString());
			parameters.Add("collapseOthers", CollapseOthers.ToString().ToLower());

			return parameters;
		}

		protected override void Unbind()
		{
			base.Unbind();
            binder.Unbind(new string[] { "State", "OnState", "OffState" });
		}

		protected override void Bind()
		{
			base.Bind();
			binder.Bind(new string[]{"State", "OnState", "OffState"});
		}

	}
}
